﻿#region License
// (c) Intergen.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace TextGlow.Control.Packaging
{
  public class ContentTypeHelper
  {
    public const string TypesTagName = "Types";
    public const string DefaultTagName = "Default";
    public const string ExtensionAttributeName = "Extension";
    public const string ContentTypeAttributeName = "ContentType";
    public const string OverrideTagName = "Override";
    public const string PartNameAttributeName = "PartName";

    public const string ContentTypesFile = "[Content_Types].xml";
    private IPackage _package;
    private IDictionary<string, string> _defaults;
    private IDictionary<Uri, string> _overrides;

    public ContentTypeHelper(IPackage package)
    {
      if (package == null)
        throw new ArgumentNullException("package");

      _package = package;

      string contentTypeXml = _package.ContentGetter.GetStringContent(ContentTypesFile);

      _defaults = CreateDefaults(contentTypeXml);
      _overrides = CreateOverrides(contentTypeXml);
    }

    private IDictionary<string, string> CreateDefaults(string contentTypeXml)
    {
      XElement document = XElement.Parse(contentTypeXml);
      XNamespace ns = XNamespace.Get("http://schemas.openxmlformats.org/package/2006/content-types");

      var defaults = from r in document.Elements(ns + DefaultTagName)
                     select new
                     {
                       Extension = (string)r.Attribute(ExtensionAttributeName),
                       ContentType = (string)r.Attribute(ContentTypeAttributeName)
                     };

      return defaults.ToDictionary(d => d.Extension, d => d.ContentType);
    }

    private IDictionary<Uri, string> CreateOverrides(string contentTypeXml)
    {
      XElement document = XElement.Parse(contentTypeXml);
      XNamespace ns = XNamespace.Get("http://schemas.openxmlformats.org/package/2006/content-types");

      var overrides = from r in document.Elements(ns + OverrideTagName)
                      select new
                      {
                        PartName = new Uri((string)r.Attribute(PartNameAttributeName), UriKind.Relative),
                        ContentType = (string)r.Attribute(ContentTypeAttributeName)
                      };

      return overrides.ToDictionary(d => d.PartName, d => d.ContentType);
    }

    public string GetContentType(Uri partUri)
    {
      string contentType;
      if (_overrides.TryGetValue(partUri, out contentType))
        return contentType;

      string partUriExtension = PackageUriHelper.GetPartExtension(partUri);
      if (_defaults.TryGetValue(partUriExtension, out contentType))
        return contentType;

      return null;
    }
  }
}
